import { Hono } from 'hono';
import { HonoContext } from '../types/hono';
import { AppError } from '../utils/error';
import { ReturnResponse } from '../utils/response';
import { OAuthService } from '../services/oauth.service';

const router = new Hono();

/**
 * OAuth路由模块
 * 处理第三方登录相关的路由
 */

/**
 * 初始化OAuth登录流程
 * @route GET /api/oauth/:provider
 * @param provider - OAuth提供商（目前支持：google）
 * @returns {object} 包含授权URL的对象
 */
router.get("/:provider", async (c: HonoContext) => {
    const provider = c.req.param("provider");
    const oauthService = new OAuthService(c);

    const authUrl = await oauthService.generateAuthUrl(provider);
    return c.json(ReturnResponse.success({ url: authUrl }));
});

/**
 * 处理OAuth回调
 * @route GET /api/oauth/:provider/callback
 * @param provider - OAuth提供商
 * @param code - 授权码（查询参数）
 * @param state - 状态参数（查询参数）
 * @returns {object} 包含JWT token的对象
 */
router.get("/:provider/callback", async (c: HonoContext) => {
    const provider = c.req.param("provider");
    const error = c.req.query("error");
    const errorDescription = c.req.query("error_description");
    const state = c.req.query("state");
    const code = c.req.query("code");

    // 首先检查state是否存在
    if (!state) {
        throw new AppError("State parameter is required");
    }

    // 处理错误情况
    if (error) {
        switch (error) {
            case 'access_denied':
                throw new AppError("User denied access", 403);
            case 'invalid_request':
                throw new AppError("Invalid OAuth request", 400);
            case 'invalid_scope':
                throw new AppError("Invalid OAuth scope", 400);
            case 'server_error':
                throw new AppError("OAuth provider server error", 502);
            default:
                throw new AppError(
                    errorDescription || `OAuth error: ${error}`,
                    400
                );
        }
    }

    // 检查授权码
    if (!code) {
        throw new AppError("Authorization code is required");
    }

    // 处理回调并验证state（移到service层统一处理）
    const oauthService = new OAuthService(c);
    const token = await oauthService.handleCallback(provider, code, state);
    return c.json(ReturnResponse.success({ token }));
});

export default router; 